
(function ($) {
    $.fn.yqGantt = function (opts, param) {
        if (typeof opts == 'string') {
            return $.fn.yqGantt.methods[opts](this, param);
        }

        return this.each(function () {
            var $this = $(this);
            var opt;
            if ($this.data("yqtype") == "yqGantt") {
                var $uniqueID = $this.attr("ID");
                var opts_ = $.extend({}, options($this));
                destroy($this);
                $this = $("#" + $uniqueID);
                opt = $.extend(opts_, opts);
            }
            else {
                opt = $.extend({}, $.fn.yqGantt.defaults, opts);
                var $uniqueID = $this.attr("ID");
                if ($uniqueID === undefined || $uniqueID === null || $uniqueID == "") {
                    $uniqueID = $.getUniqueID();
                    $this.attr("ID", $uniqueID);
                }
            }

            if (opt.width === undefined && $this.width() > 0) {
                opt.width = $this.width();
            }
            else if (typeof opt.width != "undefined") {
                $this.width(opt.width);
            }

            if (opt.height === undefined && $this.height() > 0) {
                opt.height = $this.height();
            }
            else if (typeof opt.height != "undefined") {
                $this.height(opt.height);
            }

            //变量信息
            $this.data("yqgantt_opt", opt);
            $this.data("yqtype", "yqGantt");

            opt.beforeBindingTitle.call($this, function () {
                LoadJsCss(function () {
                    init_ui($this);
                });
            });
        });
    };

    // var f_data = {
    //     "data": [
    //         {
    //             "uid": "111111",
    //             "id": 1,
    //             "wbscode": "1",
    //             "type": 1,
    //             "title": "Project #1",
    //             "startdate": "2023/08/01",
    //             "enddate": "2023/08/11",
    //             "progress": "0.00"
    //         },
    //         {
    //             "uid": "222222",
    //             "id": 2,
    //             "wbscode": "1.1",
    //             "type": 2,
    //             "parent": 1,
    //             "title": "Task #1",
    //             "startdate": "2023/08/01",
    //             "enddate": "2023/08/08",
    //             "progress": "0.50",
    //             "users": [
    //                 "1"
    //             ],
    //             "usersval": "John"
    //         },
    //         {
    //             "uid": "4mLLi1L2VpV",
    //             "id": 3,
    //             "wbscode": "1.2",
    //             "type": 2,
    //             "parent": 1,
    //             "title": "Task #2",
    //             "startdate": "2023/08/06",
    //             "enddate": "2023/08/09",
    //             "progress": "0.50",
    //             "users": [
    //                 "2",
    //                 "3"
    //             ],
    //             "usersval": "Mike,Anna"
    //         },
    //         {
    //             "uid": "4mLLi1LcXAZ",
    //             "id": 4,
    //             "wbscode": "1.3",
    //             "type": 1,
    //             "parent": 1,
    //             "title": "Task #3",
    //             "startdate": "2023/08/09",
    //             "enddate": "2023/08/11",
    //             "progress": "0.80"
    //         },
    //         {
    //             "uid": "4mLLi1LKVUK",
    //             "id": 5,
    //             "wbscode": "1.3.1",
    //             "type": 2,
    //             "parent": 4,
    //             "title": "Task #3.1",
    //             "startdate": "2023/08/09",
    //             "enddate": "2023/08/11",
    //             "progress": "0.20",
    //             "users": [
    //                 "1"
    //             ],
    //             "usersval": "John"
    //         },
    //         {
    //             "uid": "4mLLi1LneLK",
    //             "id": 6,
    //             "wbscode": "1.3.2",
    //             "type": 3,
    //             "parent": 4,
    //             "title": "Task #3.2",
    //             "startdate": "2023/08/11",
    //             "enddate": "2023/08/11"
    //         }
    //     ],
    //     "links": [
    //         {
    //             "form": "2",
    //             "to": "3"
    //         },
    //         {
    //             "form": "3",
    //             "to": "5"
    //         }
    //     ],
    //     "user": [
    //         {
    //             "id": "1",
    //             "name": "John"
    //         },
    //         {
    //             "id": "2",
    //             "name": "Mike"
    //         },
    //         {
    //             "id": "3",
    //             "name": "Anna"
    //         }
    //     ]
    // };

    $.fn.yqGantt.defaults = {
        ajaxUrl: "/Api/Base/table.html", //ajax地址
        //width: 600,
        //height: 280,
        isEdit: true,                    //是否可用，默认可用
        progressEdit: true,               //拖动进度
        showgrid: true,                  //显示表格
        showchart: true,                 //显示图表
        data: {},

        //扩展 开始
        person_add: false,
        person_class: "fa fa-sort",
        person_txt: "移动",
        person_action: function (btn) {
        },
        //扩展 结束

        beforeBindingTitle: function (callback) {
            callback();
        },
        afterBindingTitle: function () {
        },
        //onClickRow: function (rowIndex, rowData) { },  //选择行事件 null：为空
    };

    $.fn.yqGantt.methods = {
        options: function (jq) {
            return options(jq);
        },
        showchart: function (jq, tf) {  //显示、隐藏甘特图
            showchart(jq, tf);
        },
        showgrid: function (jq, tf) {  //显示、隐藏grid
            showgrid(jq, tf);
        },
        isEdit: function (jq, tf) {
            isEdit(jq, tf);
        },
        clear: function (jq) {
            clear(jq);
        },
        getData: function (jq) {
            return getData(jq);
        },
        setData: function (jq, tasks) {
            setData(jq, tasks);
        },
        resize: function (jq, para) {
            resize(jq, para);
        },
        destroy: function (jq) {
            destroy(jq);
        },
        person: function (jq) {
            options(jq).person_action.call(jq, jq.find(".person_add"));
        },

    };

    function LoadJsCss(callback) {
        //设置css
        var cssText = '';
        cssText += '       .gantt_task_cell.week_end {';
        cssText += '           background-color: #EFF5FD;';
        cssText += '       }';
        cssText += '       .gantt_task_row.gantt_selected .gantt_task_cell.week_end {';
        cssText += '           background-color: #F8EC9C;';
        cssText += '       }';
        cssText += '       .gantt_cal_ltext  {';
        cssText += '           padding: 0px 10px;';
        cssText += '       }';
        cssText += '       input, select {';
        cssText += '           height: 21px;';
        cssText += '       }';
        cssText += '       input[type="radio"] {';
        cssText += '           margin: margin: 3px 2px 5px 7px;';
        cssText += '       };';

        $.yqAddCSS(cssText, "ganttcss");

        var file = [];
        file.push({ url: "/scripts/gantt/dhtmlxgantt.js", type: "js" });
        //file.push({ url: "/scripts/gantt/gantt.js", type: "js" });
        file.push({ url: "/scripts/gantt/raven.min.js", type: "js" });
        file.push({ url: "/scripts/gantt/gantt.css", type: "css" });
        $.yqLoadJsCss(file, function () {
            callback();
        })
    }

    function options($object) {
        return $object.data("yqgantt_opt");
    }

    function showchart($object, tf) {
        var opt = options($object);
        if (tf == false && opt._gantt.config.show_grid == false) {
            opt._gantt.config.show_grid = true;
        }
        opt._gantt.config.show_chart = tf;
        opt._gantt.render();
    }

    function showgrid($object, tf) {
        var opt = options($object);
        if (tf == false && opt._gantt.config.show_chart == false) {
            opt._gantt.config.show_chart = true;
        }
        opt._gantt.config.show_grid = tf;
        opt._gantt.render();
    }

    function isEdit($object, tf) {
        var opt = options($object);
        opt._gantt.config.readonly = !tf;

        if (tf && opt.progressEdit) {
            opt._gantt.config.drag_progress = true;
        } else {
            opt._gantt.config.drag_progress = false;
        }

        opt._gantt.render();
    }

    function resize($object, para) {
        var opt = options($object);
        if (typeof para != "undefined") {
            if (typeof para.width != "undefined") {
                opt.width = para.width;
            }
            if (typeof para.height != "undefined") {
                opt.height = para.height;
            }
        }

        $object.width(opt.width);
        $object.height(opt.height);

        opt._gantt.setSizes();
    }

    function destroy($object) {
        var opt = options($object);
        opt._gantt.destructor();
        delete opt._gantt;
        $object.empty();
    }

    function clear($object) {
        var opt = options($object);
        opt._gantt.clearAll();
    }

    function init_ui($object) {
        var opt = options($object);
        var $uniqueID = $object.attr("ID");

        opt._gantt = gantt;
        //opt._gantt = Gantt.getGanttInstance();

        //设置根父项id为0
        gantt.config.root_id = "0";

        opt._gantt.config.date_format = "%Y/%m/%d";
        opt._gantt.i18n.setLocale("cn");

        opt._gantt.config.show_chart = opt.showchart;

        opt._gantt.config.show_grid = opt.showgrid;
        opt._gantt.config.show_empty_state = false;

        opt._gantt.config.readonly = !opt.isEdit;

        if (opt.isEdit && opt.progressEdit) {
            opt._gantt.config.drag_progress = true;
        } else {
            opt._gantt.config.drag_progress = false;
        }

        opt._gantt.config.auto_types = true;
        var txt_title = "标题";
        if (opt.person_add) {
            txt_title = '<a class="person_add ' + opt.person_class + '" href="javascript:$(\'#' + $uniqueID + '\').yqGantt(\'person\');">' + opt.person_txt + '</a>';
        }
        opt._gantt.config.columns = [
            { name: "text", tree: true, label: txt_title, align: "left", width: 170, min_width: 120, resize: true },
            { name: "start_date", align: "center", width: 80, resize: true },
            { name: "duration", label: "天", align: "center", width: 40, resize: true },
            // {
            //     name: "priority", label: "优先级", align: "center", width: 60, resize: true,
            //     template: function (item) {
            //         return byId(opt._gantt.serverList('priority'), item.priority)
            //     }
            // },
            // {
            //     name: "assigned", width: 80, align: "center", resize: true,
            //     template: function (item) {
            //         return byIds(opt._gantt.serverList('user'), item.users)
            //     }
            // },
            { name: "progress", label: "进度", align: "center", width: 50, resize: true, template: function (item) {
                    var _text = "";
                    var dateToStr = opt._gantt.date.date_to_str("%Y/%m/%d");
                    if (item.type != "milestone") {
                        _text = (item.progress * 100).toFixed(0) + "%";
                    }
                    return _text;
                }
            },
            {name: "weight" , width: 60, template: function (item) {
                var _text =item.weight;
                if(_text===undefined){
                    return "";
                }else{
                    return parseFloat(_text).toFixed(1) + "%";
                }
            }
            },
            {
                name: "add", width: 44
            },
        ];

        opt._gantt.plugins({
            export_api: true,
            click_drag: true,
            drag_timeline: true,// 拖动图
            marker: true,// 时间标记
            fullscreen: true,// 全屏
            tooltip: true,// 鼠标经过时信息
            undo: true // 允许撤销
            //quick_info: true, //快速信息扩展
            //tooltip: true,     //工具提示
        });

        opt._gantt.config.min_column_width = 40;
        opt._gantt.config.duration_unit = "day";
        opt._gantt.config.scale_height = 44;
        opt._gantt.config.row_height = 28;

        opt._gantt.config.scales = [
            {
                unit: "week", step: 1, format: function (date) {
                    var dateToStr = opt._gantt.date.date_to_str("%Y/%m/%d");
                    var weekNum = opt._gantt.date.date_to_str("(%W周)");
                    var endDate = opt._gantt.date.add(opt._gantt.date.add(date, 1, "week"), -1, "day");
                    return dateToStr(date) + "-" + dateToStr(endDate) + " " + weekNum(date);
                }
            },
            {
                unit: "day", step: 1, format: function (date) {
                    var dateToStr = opt._gantt.date.date_to_str("%j %D");
                    return dateToStr(date);
                }
            }
        ];

        //--工作日设置-----------------
        opt._gantt.config.work_time = true;
        opt._gantt.templates.timeline_cell_class = function (task, date) {
            if (!opt._gantt.isWorkTime(date))
                return "week_end";
            return "";
        };

        opt._gantt.templates.rightside_text = function (start, end, task) {
            if (task.type == "milestone") {
                return task.text;
            }
            return "";
        };

        //--用户---------------------
        opt._gantt.serverList("user", []);
        opt._gantt.serverList("priority",
            [{ key: 1, label: "低" },
            { key: 5, label: "中" },
            { key: 9, label: "高" }]);

        opt._gantt.locale.labels.column_text = opt._gantt.locale.labels.section_text = "标题";
        opt._gantt.locale.labels.column_assigned = opt._gantt.locale.labels.section_assigned = "负责人";
        opt._gantt.locale.labels.column_describe = opt._gantt.locale.labels.section_describe = "描述";
        opt._gantt.locale.labels.column_priority = opt._gantt.locale.labels.section_priority = "优先级";
        opt._gantt.locale.labels.column_weight = opt._gantt.locale.labels.section_weight = "权重";

        //编辑页面设置
        //任务组
        opt._gantt.config.lightbox.project_sections = [
            { name: "text", height: 21, map_to: "text", type: "textarea", focus: true },
            { name: "describe", height: 70, map_to: "describe", type: "textarea" },
            { name: "type", height: 30, type: "typeselect", map_to: "type" }
        ];

        opt._gantt.form_blocks["my_editor"] = {
            render: function (sns) {
                return '<div style="height:25px;padding:0 10px;">'+
                    '<input onkeyup="if(!/^[0-9]+$/.test(value)) value=value.replace(/^(\-)*(\d+)\.(\d\d).*$/,\'$1$2.$3\'); if(value>100) value=100;  if(value<0) value=null; if((value[0] == 0 && value[1] > 0) || value == \'00\') value=value.slice(1);" style="width:40px;font-size:13px;box-sizing:border-box;border:1px solid #cecece;outline: none !important;" type="text"/>%  取值范围：0-100，保留2位小数'+
                    '</div>';
            },
            set_value: function (node, value, task) {
                if(value===undefined){
                    value=null;
                }
                node.querySelector("input").value = value;
                node.querySelector("input")
            },
            get_value: function (node, task) {
                var value= node.querySelector("input").value;
                if (Number(value)!==parseFloat(value)) { 
                    return ''
                }
                if (value < 0) { 
                    return 0;
                } else if (value >= 100) { 
                    return 100;
                } else {
                    return value.toString().match(/^\d+(?:\.\d{0,1})?/) 
                }
            },
            focus: function (node) {
                var a = node.querySelector("input");
                a.select();
                a.focus();
            }
        };


        //任务
        opt._gantt.config.lightbox.task_sections = [
            { name: "text", height: 21, map_to: "text", type: "textarea", focus: true },
            { name: "describe", height: 70, map_to: "describe", type: "textarea" },
            { name: "type", type: "typeselect", map_to: "type" },
            {
                name: "priority", type: "radio", map_to: "priority", options: opt._gantt.serverList("priority"),
                onchange: function () {
                    //console.log("checkbox switched");
                }
            },
            { name: "time", type: "duration", map_to: "auto" },
            { name: "weight", height: 21, map_to: "weight", type: "my_editor" },
            { name: "assigned", type: "checkbox", map_to: "users", options: opt._gantt.serverList("user"),
                onchange: function () {
                }
            },
        ];
 
        //里程碑
        opt._gantt.config.lightbox.milestone_sections = [
            { name: "text", height: 21, map_to: "text", type: "textarea", focus: true },
            { name: "describe", height: 70, map_to: "describe", type: "textarea" },
            { name: "type", type: "typeselect", map_to: "type" },
            { name: "time", type: "duration", map_to: "auto" },
        ];

        //--表格日期格式显示----------------------------------
        opt._gantt.templates.task_end_date = function (date) {
            return opt._gantt.templates.task_date(new Date(date.valueOf() - 1));
        };

        var gridDateToStr = opt._gantt.date.date_to_str("%Y/%m/%d");
        opt._gantt.templates.grid_date_format = function (date, column) {
            if (column === "end_date") {
                return gridDateToStr(new Date(date.valueOf() - 1));
            } else {
                return gridDateToStr(date);
            }
        }
        //-----------------------------------------------------

        //--自定义甘特图上文本显示-------------------------------
        opt._gantt.templates.task_text = function (start, end, item) {
            //console.log("task.users", item.users);
            if (item.users === undefined) {
                return item.text;
            } else {
                if (item.users === undefined) {
                    item.users = [];
                }

                return item.text + (item.users.length == 0 ? "" : "(" + byIds(opt._gantt.serverList('user'), item.users) + ")");
            }
        };

        //--tooltip显示------------------------------------------
        opt._gantt.templates.tooltip_text = function (start, end, item) {
            //console.log(item);
            var _text = "";
            var dateToStr = opt._gantt.date.date_to_str("%Y/%m/%d");
            if (item.type == "project") {
                _text = "<b>标题:</b> " + item.text;
                _text += "</br><b>时间:</b>" + dateToStr(item.start_date) + "至" + dateToStr(item.end_date);
                _text += "</br><b>持续时间:</b>" + item.duration;
            } else if (item.type == "milestone") {
                _text = "<b>标题:</b> " + item.text;
                _text += "</br><b>时间:</b>" + dateToStr(item.start_date);
            } else {
                _text = "<b>标题:</b> " + item.text;
                _text += "</br><b>优先级:</b>" + byId(opt._gantt.serverList('priority'), item.priority);
                _text += "</br><b>时间:</b>" + dateToStr(item.start_date) + "至" + dateToStr(item.end_date);
                _text += "</br><b>持续时间:</b>" + item.duration;
                if (item.users === undefined) {
                    item.users = [];
                }
                _text += item.users.length == 0 ? "" : ("</br><b>负责人:</b>" + byIds(opt._gantt.serverList('user'), item.users));
                _text += "</br><b>进度:</b>" + (item.progress * 100).toFixed(0) + "%";
            }
            return _text;
        };

        //--设置是否可以编辑------------------------------
        opt._gantt.templates.grid_row_class =
            opt._gantt.templates.task_row_class = function (start, end, task) {
                if (opt._gantt.isReadonly(task.id)) {
                    return "readonly"
                };
            };
        opt._gantt.templates.task_class = function (start, end, task) {
            if (opt._gantt.isReadonly(task.id)) {
                return "readonly_bar"
            };
        };

        opt._gantt.attachEvent("onTaskDblClick", function (id, e) {
            if (opt._gantt.isReadonly(id)) {
                return false;
            } else {
                opt._gantt.showLightbox(id)
                return true;
            }
        });

        opt._gantt.attachEvent("onLightboxSave", function (id, task, is_new) {
            if (opt._gantt.isReadonly(id)) {
                opt._gantt.alert("You cannot edit this task");
                return false;
            }

            return true;
        })
        //------------------------------------------------

        opt._gantt.init($uniqueID);
        setData($object, opt.data);

        opt.afterBindingTitle.call($object);
    }

    function byId(list, id) {
        if (id === undefined) {
            return "";
        }

        for (var i = 0; i < list.length; i++) {
            if (list[i].key == id)
                return list[i].label || "";
        }
        return "";
    }

    function byIds(list, ids) {
        if (ids === undefined) {
            return "";
        }

        var vals = "";
        for (var i = 0; i < list.length; i++) {
            for (var j = 0; j < ids.length; j++) {
                if (list[i].key == ids[j]) {
                    vals += (vals == "" ? "" : ",") + list[i].label;
                }
            }
        }
        return vals;
    }

    function getData($object) {
        var opt = options($object);

        var list = opt._gantt.serialize();
        //console.log(JSON.stringify(list, null, 3));
        for (var index = 0; index < list.data.length; index++) {
            list.data[index]._id = (index + 1);
            list.data[index].wbscode = opt._gantt.getWBSCode(opt._gantt.getTask(list.data[index].id));
        }
        for (var i = 0; i < list.data.length; i++) {
            var parent = list.data[i].parent;
            if (!(parent === undefined || parent == "0")) {
                for (var j = 0; j < list.data.length; j++) {
                    if (parent == list.data[j].id) {
                        list.data[i].parent = list.data[j]._id;
                        break;
                    }
                }
            }
        }

        for (var i = 0; i < list.data.length; i++) {
            var id_ = list.data[i].id;
            for (var l = 0; l < list.links.length; l++) {
                if (list.links[l].source == id_) {
                    list.links[l].source = list.data[i]._id;
                }
                if (list.links[l].target == id_) {
                    list.links[l].target = list.data[i]._id;
                }
            }

            list.data[i].id = list.data[i]._id;
            delete list.data[i]._id;
        }

        //console.log(JSON.stringify(list, null, 3));
        var data = JSON.parse(JSON.stringify(list.data));

        for (var i = 0; i < data.length; i++) {
            var row = {};
            if (data[i].uid === undefined) {
                data[i].uid = $.getShortID();
            }
            row.uid = data[i].uid;
            row.id = data[i].id;
            row.wbscode = data[i].wbscode;

            if (data[i].type === undefined) {
                data[i].type = "task";
            }
            if (data[i].type == "project") {
                row.type = 1;
            } else if (data[i].type == "task") {
                row.type = 2;
            }
            else if (data[i].type == "milestone") {
                row.type = 3;
            }
        

            if (data[i].parent != "0") {
                row.parent = data[i].parent;
            }
            delete data[i].parent;

            row.title = data[i].text;
            row.startdate = data[i].start_date;
            row.enddate = data[i].end_date;
            delete data[i].text;
            delete data[i].start_date;
            delete data[i].end_date;

            if (data[i].type == "task" && data[i].users === undefined) {
                data[i].users = [];
            }

            //进度四舍五入，保留2位数
            if (data[i].type == "project" || data[i].type == "task") {
                row.progress = data[i].progress.toFixed(2);
            }
            delete data[i].progress;

            if (data[i].type == "task") {
                row.users = data[i].users;
                row.usersval = byIds(opt._gantt.serverList('user'), data[i].users);

                row.weight = data[i].weight;
                if (!(row.weight === undefined)) {
                    row.weight = parseFloat(row.weight);
                }
            }
            delete data[i].users;
            delete data[i].usersval;
            delete data[i].weight;
            delete data[i].type;

            data[i] = $.extend(data[i], row);
        }

        var user_ = [];
        if (!(opt.data.user === undefined)) {
            user_ = JSON.parse(JSON.stringify(opt.data.user));
        }

        var links = list.links;
        var links_ = [];
        for (var i = 0; i < links.length; i++) {
            links_.push({
                //id: links[i].id,
                form: links[i].source,
                to: links[i].target
            });
            //type=1
        }

        opt.data = { data: data, links: links_, user: user_ };
        //console.log("data", list, opt.data);
        return opt.data;
    }

    function setData($object, tasks) {
        var opt = options($object);

        opt._gantt.clearAll();
        if (tasks.data === undefined) {
            tasks.data = [];
        }
        if (tasks.links === undefined) {
            tasks.links = [];
        }
        if (tasks.user === undefined) {
            tasks.user = [];
        }

        opt.data = tasks;

        var user = tasks.user;
        var user_ = [];
        for (var i = 0; i < user.length; i++) {
            user_.push({
                key: user[i].id,
                label: user[i].name
            });
        }

        opt._gantt.serverList("user", user_);
        if (tasks.links === undefined) {
            tasks.links = [];
        }
        var data_ = JSON.parse(JSON.stringify(tasks.data));
        for (var i = 0; i < data_.length; i++) {
            if (data_[i].type == 1) {
                data_[i].type = "project";
            } else if (data_[i].type == 2) {
                data_[i].type = "task";
            }
            else if (data_[i].type == 3) {
                data_[i].type = "milestone";
            }

            if (data_[i].parent === undefined) {
                data_[i].parent = 0;
            }

            if (data_[i].text === undefined) {
                data_[i].text = data_[i].title;
                delete data_[i].title;
            }
            if (data_[i].start_date === undefined) {
                data_[i].start_date = data_[i].startdate;
                delete data_[i].startdate;
            }
            if (data_[i].end_date === undefined) {
                data_[i].end_date = data_[i].enddate;
                delete data_[i].enddate;
            }

            if (data_[i].type == "project" || data_[i].type == "task") {
                data_[i].open = true;
            }

            if (data_[i].type == "task") {
                delete data_[i].type;
            }
        }

        //任务
        for (var i = 0; i < opt._gantt.config.lightbox.task_sections.length; i++) {
            if (opt._gantt.config.lightbox.task_sections[i].name == "assigned") {
                opt._gantt.config.lightbox.task_sections[i].options = opt._gantt.serverList("user");
                break;
            }
        }

        var links = tasks.links;
        var links_ = [];
        for (var i = 0; i < links.length; i++) {
            links_.push({
                id: (i + 1),
                source: links[i].form,
                target: links[i].to,
                type: "0"
            });
        }

        //opt._gantt.render();
        opt._gantt.parse({ data: data_, links: links_ });
    }
})(jQuery);